package com.xyf.sys.service.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.alibaba.excel.EasyExcel;
import com.xyf.sys.domain.Dept;
import com.xyf.sys.domain.OrderAddress;
import com.xyf.sys.domain.OrderProduct;
import com.xyf.sys.domain.SysDownloadTask;
import com.xyf.sys.domain.User;
import com.xyf.sys.enums.DeliveryEnum;
import com.xyf.sys.mapper.SysDownloadTaskMapper;
import com.xyf.sys.service.IDeptService;
import com.xyf.sys.service.IDownloadTaskService;
import com.xyf.sys.service.IOrderAddressService;
import com.xyf.sys.service.IOrderProductService;
import com.xyf.sys.service.IOrderService;
import com.xyf.sys.service.ITencentCloudService;
import com.xyf.sys.service.IUserRoleService;
import com.xyf.sys.service.IUserService;
import com.xyf.sys.util.CsvGenerator;
import com.xyf.sys.util.ExcelToCsv;
import com.xyf.sys.vo.BillData;
import com.xyf.sys.vo.OrderBill;
import com.xyf.sys.vo.OrderBillVerify;
import com.xyf.sys.vo.OrderExport;
import com.xyf.sys.vo.OrderPayment;
import com.xyf.sys.vo.OrderVo;
import com.xyf.sys.vo.OrderWeightWriteVo;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author R-H
 * @Date 2024/5/61921
 * @Description
 */
@Service
@Slf4j
public class DownloadTaskServiceImpl implements IDownloadTaskService {

    @Autowired
    private SysDownloadTaskMapper mapper;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private ITencentCloudService tencentCloudService;
    @Autowired
    @Qualifier("threadPoolTaskExecutor")
    private Executor executor;
    @Autowired
    private IUserService userService;
    @Autowired
    private IDeptService deptService;
    @Autowired
    private IOrderProductService orderProductService;
    @Autowired
    private ExcelToCsv excelToCsv;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private IOrderAddressService orderAddressService;

    @Override
    public Long save(String userId, String subUserId, String startDate, String endDate, Integer type, Long subDeptId, Long deptId) {
        SysDownloadTask task = new SysDownloadTask();
        task.setUserId(userId);
        task.setSubUserId(subUserId == null ? userId : subUserId);
        task.setSubDeptId(subDeptId == null ? deptId : subDeptId);
        task.setDeptId(deptId);
        task.setStartDate(startDate);
        task.setEndDate(endDate);
        task.setType(type);
        task.setDelFlag("0");
        task.setStatus("0");
        task.setCreateTime(new Date());
        task.setCreateBy(userId);
        mapper.insert(task);
        return task.getId();
    }

    @Override
    public void update(SysDownloadTask task) {
        task.setUpdateTime(new Date());
        mapper.updateByPrimaryKeySelective(task);
    }

    @Override
    public List<SysDownloadTask> list(String userId) {
        List<SysDownloadTask> tasks = mapper.selectByUserId(userId);
        tasks.stream().filter(t -> t.getSubUserId() != null).forEach(t -> t.setName(userService.get(t.getSubUserId()).getName()));
        return tasks;
    }

    @Override
    public List<SysDownloadTask> list(Long deptId) {
        List<SysDownloadTask> tasks = mapper.selectByDeptId(deptId);
        tasks.stream().filter(t -> t.getSubDeptId() != null).forEach(t -> t.setName(deptService.get(t.getSubDeptId()) != null ? deptService.get(t.getSubDeptId()).getDeptName() : null));
        return tasks;
    }

    @Override
    public Long createTask(String startDate, String endDate, Integer orderType, String userId, String subUserId, Integer type, Long deptId, Long subDeptId, Integer checkType) {
        Long id = this.save(userId, subUserId == null ? userId : subUserId, startDate, endDate, type, subDeptId, deptId);
        executor.execute(() -> executeAsyncTask(id, startDate, endDate, orderType, subUserId == null ? userId : subUserId, subDeptId, deptId, checkType));
        return id;
    }

    @Override
    public Long createTask(String fileUrl, String userId, Long deptId) {
        Long taskId = this.save(userId, null, null, null, 2, null, deptId);
        executor.execute(() -> {
            try {
                executeBill(taskId, fileUrl, userId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return taskId;
    }

    @Override
    public Long createOrderWeightWriteTask(String url, String userId, Long deptId) {
        Long taskId = this.save(userId, null, null, null, 3, null, deptId);
        executor.execute(() -> {
            try {
                executeWriteOrderWeightTask(taskId, url, userId);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        return taskId;
    }

    @Override
    public Object createOrderExportTask(OrderExport body, Long deptId) {
        Long taskId = this.save(body.getUserId(), null, body.getStartTime(), body.getEndTime(), 4, null, deptId);
        executor.execute(() -> exeOrderExport(taskId));
        return taskId;
    }

    private void exeOrderExport(Long taskId) {
        SysDownloadTask task = mapper.selectByPrimaryKey(taskId);
        List<OrderPayment> list = orderService.findExportOrderData(task.getUserId(), task.getStartDate(), task.getEndDate());
        User user = userService.get(task.getUserId());
        Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"));
        log.info("tempDir {}", tempDir);
        String filePath = tempDir + "/" + user.getName() + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年MM月")) + "订单" + System.currentTimeMillis() / 1000 + ".csv";
        Dept dept = deptService.get(task.getDeptId());
        String dir = tempDir + "/" + "收款记录" + "/";
        String file = CsvGenerator.generateOrderExportCsv(dir, task.getStartDate(), task.getEndDate(), list, dept.getDeptName());
        String url = tencentCloudService.upload(file);
        task.setUrl(url);
        task.setStatus("1");
        this.update(task);
    }

    private void executeBill(Long taskId, String fileUrl, String userId) throws Exception {
        SysDownloadTask task = mapper.selectByPrimaryKey(taskId);
        User user = userService.get(userId);
        Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"));
        log.info("tempDir {}", tempDir);
        String filePath = tempDir + "/" + user.getName() + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年MM月")) + "对账单" + System.currentTimeMillis() / 1000 + ".csv";
        excelToCsv.convertExcelToCsv(fileUrl, filePath);
        log.info("filePath {}", filePath);
        String url = tencentCloudService.upload(filePath);
        task.setUrl(url);
        task.setStatus("1");
        this.update(task);
    }

    private void executeBillTask(Long taskId, String fileUrl, String userId) throws IOException {
        SysDownloadTask task = mapper.selectByPrimaryKey(taskId);
        List<BillData> list = null;
        try {
            URL url = new URL(fileUrl);
            URLConnection connection = url.openConnection();
            list = EasyExcel.read(connection.getInputStream())
                    .head(BillData.class)
                    .sheet()
                    .doReadSync();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("bill task err -> {}", e);
        }
        if (CollectionUtils.isEmpty(list)) {
            task.setRemark("EXCEL表无对账数据");
            mapper.updateByPrimaryKey(task);
            return;
        }
        DecimalFormat format = new DecimalFormat("#.00");
        format.setMaximumFractionDigits(2);
        // 设置进位方式
        format.setRoundingMode(RoundingMode.HALF_UP);
        List<OrderBillVerify> billVerifyList = new ArrayList<>(list.size());
        for (BillData billData : list) {
            if (StringUtils.isBlank(billData.getOrderNumber()) || billData.getSettlementWeight() == null) {
                continue;
            }
            OrderBill orderBill = orderService.findByWaybillId(billData.getOrderNumber());
            OrderBillVerify billVerify = new OrderBillVerify();
            if (orderBill != null) {
                BigDecimal weight = orderBill.getWeight() == null ? BigDecimal.ZERO : orderBill.getWeight();
                BigDecimal price = orderBill.getPrice() == null ? BigDecimal.ZERO : orderBill.getPrice().multiply(new BigDecimal("0.01"));
                Double dueToLeader = getDueToLeader(orderBill.getReceiverProvince(), price.doubleValue(), weight.setScale(0, RoundingMode.CEILING).doubleValue(), orderBill.getDeliveryId(), orderBill.getLogisticPriceSchemeId(), orderBill.getCreateTime());
                String profitFormula = getProfitFormula(orderBill.getReceiverProvince(), price.doubleValue(), dueToLeader, orderBill.getLogisticPriceSchemeId(), weight.setScale(0, RoundingMode.CEILING).intValue(), orderBill.getDeliveryId(), orderBill.getCreateTime());
                BigDecimal actualCost = culActualCost(orderBill.getDeliveryId(), billData.getOverWeight());
                BigDecimal profit = price.subtract(new BigDecimal(dueToLeader.toString())).subtract(actualCost);
                billVerify.setName(orderBill.getName());
                billVerify.setWeightDifference(Double.valueOf(weight.toString()) - billData.getSettlementWeight());
                billVerify.setWeight(Double.parseDouble(format.format(weight)));
                billVerify.setRetailPrice(price.doubleValue());
                billVerify.setDueToLeader(Double.parseDouble(format.format(dueToLeader)));
                billVerify.setActualCost(Double.parseDouble(format.format(actualCost)));
                billVerify.setProfitFormula(profitFormula);
                billVerify.setProfit(Double.parseDouble(format.format(profit)));
                billVerify.setLogisticPriceSchemeId(orderBill.getLogisticPriceSchemeId());
                billVerify.setOverWeightAmount(orderBill.getOverWeightAmount());
            } else {
                billVerify.setName("《运单不存在》");
            }
            BeanUtils.copyProperties(billData, billVerify);
            billVerifyList.add(billVerify);
        }
        User user = userService.get(userId);
        Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"));
        log.info("tempDir {}", tempDir);
        String filePath = tempDir + "/" + user.getName() + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年MM月")) + "对账单" + System.currentTimeMillis() / 1000 + ".xls";
        log.info("filePath {}", filePath);
        EasyExcel.write(filePath, OrderBillVerify.class).sheet("对账单").doWrite(billVerifyList);
        String url = tencentCloudService.upload(filePath);
        task.setUrl(url);
        task.setStatus("1");
        this.update(task);
    }

    private void executeAsyncTask(Long taskId, String startDate, String endDate, Integer type, String userId, Long subDeptId, Long deptId, Integer checkType) {
        SysDownloadTask task = mapper.selectByPrimaryKey(taskId);
        // 异步任务的逻辑
        List<OrderPayment> list = orderService.paymentDetailList(startDate, endDate, type, userId, deptId, subDeptId, checkType);
        Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"));
        BigDecimal totalPayment = BigDecimal.ZERO;
        BigDecimal deliveryAmount = BigDecimal.ZERO;
        BigDecimal laundryAmount = BigDecimal.ZERO;
        Integer totalWeightDiff = 0;
        for (OrderPayment orderPayment : list) {
            orderPayment.setAmount(orderPayment.getAmount().multiply(new BigDecimal("0.01")).setScale(2, RoundingMode.HALF_UP));
            OrderVo order = orderService.getDetail(orderPayment.getOrderId());
            if (order.getOrderType() == 1) {
                BigDecimal price = orderPayment.getAmount();
                List<OrderProduct> productList = order.getProductList();
                if (CollectionUtils.isEmpty(productList)) {
                    continue;
                }
                OrderProduct orderProduct = productList.get(0);
                OrderAddress receiverAddress = orderProduct.getRecMan();
                Long logisticPriceSchemeId = orderProduct.getLogisticPriceSchemeId();
                if (logisticPriceSchemeId == null) {
                    User user = userService.get(order.getRegimentId());
                    logisticPriceSchemeId = user.getLogisticPriceSchemeId();
                }
                if (StringUtils.isBlank(orderProduct.getWeight())) {
                    orderPayment.setRegimentProfit(BigDecimal.ZERO);
                    orderPayment.setProfitFormula("");
                    orderPayment.setReceiverProvince(receiverAddress.getProvince());
                    orderPayment.setDeliveryName(orderProduct.getDeliveryName());
                    orderPayment.setBusinessDescription(orderProduct.getItemType());
                    orderPayment.setWeight("");
                    continue;
                }
                BigDecimal weight = new BigDecimal(orderProduct.getWeight());
                Double dueToLeader = getDueToLeader(receiverAddress.getProvince(), price.doubleValue(), weight.setScale(0, RoundingMode.CEILING).doubleValue(), orderProduct.getDeliveryId(), logisticPriceSchemeId, order.getCreateTime());
                String profitFormula = getProfitFormula(receiverAddress.getProvince(), price.doubleValue(), dueToLeader, logisticPriceSchemeId, weight.setScale(0, RoundingMode.CEILING).intValue(), orderProduct.getDeliveryId(), order.getCreateTime());
                BigDecimal actualCost = culActualCost(orderProduct.getDeliveryId(), weight.setScale(0, RoundingMode.CEILING).doubleValue());
                BigDecimal profit = price.subtract(new BigDecimal(dueToLeader.toString())).subtract(actualCost);
                if (order.getOrderStatus() == 2 && DeliveryEnum.SF.toString().equalsIgnoreCase(orderProduct.getDeliveryId())) {
                    orderPayment.setRegimentProfit(BigDecimal.ZERO);
                    profitFormula = "0%";
                    dueToLeader = 0.0;
                }
                if (order.getOrderStatus() == 2 && DeliveryEnum.JD.toString().equals(orderProduct.getDeliveryId())) {
                    profitFormula = "";
                    logisticPriceSchemeId = null;
                    BigDecimal calculateWeight = weight.setScale(0, RoundingMode.CEILING);
                    if (new BigDecimal("3").compareTo(calculateWeight) == -1) {
                        dueToLeader = calculateWeight.multiply(new BigDecimal("0.5")).setScale(2, RoundingMode.HALF_UP).doubleValue();
                    } else {
                        dueToLeader = 1.0;
                    }
                }
                if (order.getOrderStatus() == 2 && DeliveryEnum.EMS.toString().equals(orderProduct.getDeliveryId())) {
                    profitFormula = "";
                    logisticPriceSchemeId = null;
                    BigDecimal calculateWeight = weight.setScale(0, RoundingMode.CEILING);
                    BigDecimal regimentProfit = new BigDecimal("2");
                    if (new BigDecimal("3").compareTo(calculateWeight) == -1) {
                        BigDecimal subtract = calculateWeight.subtract(new BigDecimal("3"));
                        regimentProfit = regimentProfit.add(subtract);
                        dueToLeader = regimentProfit.doubleValue();
                    } else {
                        dueToLeader = 2.0;
                    }
                }
                
                if (DeliveryEnum.JTSD.toString().equals(orderProduct.getDeliveryId()) && weight.setScale(0, RoundingMode.CEILING).doubleValue() == 1.0d) {
                    if(price.doubleValue() == 5.0d) {
                        dueToLeader = 2.1d;
                        profitFormula = "5-2.9";
                    }
                    if(price.doubleValue() == 6.0d) {
                        dueToLeader = 2.8d;
                        profitFormula = "6-3.2";
                    }
                }
                if (orderPayment.getRefundStatus() != null && orderPayment.getRefundStatus() == 2) {
                    dueToLeader = 0.0;
                    profitFormula = "";
                }
                orderPayment.setRegimentProfit(new BigDecimal(dueToLeader).setScale(2, RoundingMode.HALF_UP));
                orderPayment.setProfitFormula(profitFormula);
                orderPayment.setLogisticPriceSchemeId(logisticPriceSchemeId);
                if (orderPayment.getRefundStatus() == null || orderPayment.getRefundStatus() != 2) {
                    totalPayment = totalPayment.add(orderPayment.getRegimentProfit());
                    deliveryAmount = deliveryAmount.add(orderPayment.getRegimentProfit());
                }
                orderPayment.setReceiverProvince(receiverAddress.getProvince());
                orderPayment.setDeliveryName(orderProduct.getDeliveryName());
                orderPayment.setBusinessDescription(orderProduct.getItemType());
                orderPayment.setWeight(weight.toPlainString());
                if (StringUtils.isNotBlank(orderProduct.getSettleWeight()) && StringUtils.isNotBlank(orderProduct.getWeight())) {
                    int weightDiff = weight.setScale(0, RoundingMode.CEILING).intValue() - new BigDecimal(orderProduct.getSettleWeight()).setScale(0, RoundingMode.CEILING).intValue();
                    if (weightDiff < -1) {
                        totalWeightDiff += weightDiff;
                    }
                    orderPayment.setWeightDiff(Integer.toString(weightDiff));
                }
            }
            if (order.getOrderType() == 2) {
                if (checkType == 2) {
                    BigDecimal decimal = orderPayment.getAmount().multiply(new BigDecimal("0.476")).setScale(2, RoundingMode.HALF_UP);
                    orderPayment.setRegimentProfit(decimal);
                    orderPayment.setProfitFormula("47.6%");
                } else {
                    BigDecimal decimal = orderPayment.getAmount().multiply(new BigDecimal("0.3")).setScale(2, RoundingMode.HALF_UP);
                    orderPayment.setRegimentProfit(decimal);
                    orderPayment.setProfitFormula("30%");
                }
                orderPayment.setDeliveryName("干洗");
                if (orderPayment.getRefundStatus() == null || orderPayment.getRefundStatus() != 2) {
                    totalPayment = totalPayment.add(orderPayment.getRegimentProfit());
                    laundryAmount = laundryAmount.add(orderPayment.getRegimentProfit());
                } else {
                    orderPayment.setRegimentProfit(BigDecimal.ZERO);
                    orderPayment.setProfitFormula("0%");
                }
            }
            if (order.getOrderType() == 4) {
                List<OrderAddress> addressList = orderAddressService.getAddressList(order.getId());
                if (addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().isPresent()) {
                    OrderAddress receiverAddress = addressList.stream().filter(orderAddress -> orderAddress.getType() == 2).findFirst().get();
                    orderPayment.setReceiverMobile(receiverAddress.getMobile());
                    String address = receiverAddress.getProvince() + receiverAddress.getCity() + receiverAddress.getArea() + receiverAddress.getTown() + receiverAddress.getAddress();
                    address = "\"" + address.replace("\"", "\"\"") + "\"";
                    orderPayment.setReceiverAddress(address);

                }
            }
        }
//        User user = userService.get(task.getSubUserId());
        Dept dept = deptService.get(task.getSubDeptId());

        String dir = tempDir + "/" + "收款记录" + "/";
        String filePath = CsvGenerator.generateCsv(dir, startDate, endDate, list, dept.getDeptName(), totalPayment, deliveryAmount, laundryAmount, checkType == 2);
        String url = tencentCloudService.upload(filePath);
        task.setUrl(url);
        task.setStatus("1");
        this.update(task);
    }

    private void executeWriteOrderWeightTask(Long taskId, String fileUrl, String userId) throws IOException {
        SysDownloadTask task = mapper.selectByPrimaryKey(taskId);
        List<OrderWeightWriteVo> list = null;
        try {
            URL url = new URL(fileUrl);
            URLConnection connection = url.openConnection();
            list = EasyExcel.read(connection.getInputStream())
                    .head(OrderWeightWriteVo.class)
                    .sheet()
                    .doReadSync();
        } catch (IOException e) {
            e.printStackTrace();
            log.error("order weight write task err -> {}", e);
        }
        if (CollectionUtils.isEmpty(list)) {
            task.setRemark("EXCEL表无数据");
            mapper.updateByPrimaryKey(task);
            return;
        }
        for (OrderWeightWriteVo weightWriteVo : list) {
            if (StringUtils.isBlank(weightWriteVo.getOrderNumber()) || weightWriteVo.getWeight() == null) {
                continue;
            }
            OrderProduct orderProduct = orderProductService.find(weightWriteVo.getOrderNumber());
            if (orderProduct == null) {
                continue;
            }
            orderProduct.setSettleWeight(weightWriteVo.getWeight());
            orderProduct.setOverWeightAmount(StringUtils.isBlank(weightWriteVo.getOverWeightAmount()) ? BigDecimal.ZERO : new BigDecimal(weightWriteVo.getOverWeightAmount()));
            orderProduct.setUpdateTime(new Date());
            orderProductService.update(orderProduct);
        }
        task.setUrl(fileUrl);
        task.setStatus("1");
        this.update(task);
    }


    private static void createCell(Row row, int columnIndex, String value, CellStyle style) {
        Cell cell = row.createCell(columnIndex);
        cell.setCellValue(value);
        cell.setCellStyle(style);
    }

    private static void fillData(Sheet sheet, List<OrderPayment> orderPaymentList, CellStyle style) {
        // 从第三行开始填充数据
        int rowNum = 2;
        for (OrderPayment orderPayment : orderPaymentList) {
            Row row = sheet.createRow(rowNum++);
            createCell(row, 0, orderPayment.getName(), style);
            createCell(row, 1, orderPayment.getPaymentDate(), style);
            createCell(row, 2, DateUtil.format(orderPayment.getRefundTime(), "yyyy-MM-dd HH:mm:ss"), style);
            createCell(row, 3, orderPayment.getWeightDiff(), style);
            createCell(row, 4, orderPayment.getWeight(), style);
            createCell(row, 5, orderPayment.getSettleWeight(), style);
            createCell(row, 6, orderPayment.getAmount().toPlainString(), style);
            createCell(row, 7, orderPayment.getOverWeightAmount() == null ? "" : orderPayment.getOverWeightAmount().toPlainString(), style);
            createCell(row, 8, orderPayment.getRegimentProfit() == null ? BigDecimal.ZERO.toPlainString() : orderPayment.getRegimentProfit().setScale(2, RoundingMode.HALF_UP).toPlainString(), style);
            createCell(row, 9, orderPayment.getProfitFormula(), style);
            createCell(row, 10, orderPayment.getLogisticPriceSchemeId() == null ? "" : orderPayment.getLogisticPriceSchemeId().toString(), style);
            createCell(row, 11, orderPayment.getOrderId(), style);
            createCell(row, 12, orderPayment.getDeliveryName(), style);
            createCell(row, 13, orderPayment.getWaybillId(), style);
            createCell(row, 14, orderPayment.getBusinessDescription(), style);
            createCell(row, 15, orderPayment.getReceiverProvince(), style);
            createCell(row, 16, orderPayment.getNote(), style);
        }
    }

    public static BigDecimal culActualCost(String deliveryId, Double excelValue) {
        BigDecimal extral = BigDecimal.ZERO;
        if (excelValue != null) {
            extral = new BigDecimal(excelValue);
        }
        if (DeliveryEnum.JTSD.toString().equals(deliveryId)) {
            return new BigDecimal("2.1").add(extral);
        }
        if (DeliveryEnum.STO.toString().equals(deliveryId)) {
            return new BigDecimal("2.9").add(extral);
        }
        if (DeliveryEnum.YUNDA.toString().equals(deliveryId)) {
            return new BigDecimal("3").add(extral);
        }
        if (DeliveryEnum.EMS.toString().equals(deliveryId)) {
            return new BigDecimal("2.9").add(extral);
        }
        if (DeliveryEnum.YTO.toString().equals(deliveryId)) {
            return new BigDecimal("2.9").add(extral);
        }
        return BigDecimal.ZERO;
    }

    public static Double getDueToLeader(String receiverAddress, Double price, Double weight, String deliveryId, Long regimentPriceScheme, Date orderDate) {
        /**
         * 新疆：首重15（12）+续重10（8）
         * 海南：首重12（8）+续重5（3）
         * 西藏：首重18（15）+续重12（10）
         * 内蒙古：首重10（8）+续重6（5）（阔内为团长成本）仅 极兔申通
         */
        if (receiverAddress.contains("新疆") || receiverAddress.contains("西藏")) {
            return (Math.ceil(weight) * 2 + 1);
        }
        if (receiverAddress.contains("海南")) {
            return (Math.ceil(weight) * 2 + 2);
        }
        if (receiverAddress.contains("北京") || receiverAddress.contains("上海")) {
            return (getProfitSharingRatio(regimentPriceScheme, weight.intValue(), deliveryId, orderDate) * price) - 1;
        }
        if (receiverAddress.contains("内蒙古") && (DeliveryEnum.JTSD.toString().equals(deliveryId) || DeliveryEnum.STO.toString().equals(deliveryId))) {
            return (Math.ceil(weight) * 1 + 1);
        }
        return (getProfitSharingRatio(regimentPriceScheme, weight.intValue(), deliveryId, orderDate) * price);
    }

    public static Double getProfitSharingRatio(Long regimentPriceScheme, Integer weight, String deliveryId, Date orderDate) {
        if (regimentPriceScheme == null || weight == null) {
            return 0.0;
        }
        Date thresholdDate = DateUtil.parse("2025-10-04 22:29:02", "yyyy-MM-dd HH:mm:ss");
        boolean isJtDelivery = (DeliveryEnum.JTSD.toString().equals(deliveryId) || "极兔快递".equals(deliveryId));
        boolean isAfterThreshold = (orderDate != null && orderDate.after(thresholdDate));

        if (isJtDelivery && isAfterThreshold) {
            switch (weight) {
                case 1:
                    return 0.42;
                case 2:
                    return 0.43;
                case 3:
                    return 0.45;
                default:
                    return 0.40;
            }
        }
        if (regimentPriceScheme.equals(2L)) {
            switch (weight) {
                case 1:
                    return 0.42;
                case 2:
                    return 0.51;
                case 3:
                    return 0.55;
                default:
                    return 0.50;
            }
        } else {
            switch (weight) {
                case 1:
                    return 0.42;
                case 2:
                    return 0.43;
                case 3:
                    return 0.45;
                default:
                    return 0.40;
            }
        }
    }

    public static String getProfitFormula(String receiverAddress, Double price, Double duToLeader, Long regimentPriceScheme, Integer weight, String deliveryId, Date orderDate) {
        DecimalFormat decimalFormat = new DecimalFormat("#.##");
        if (receiverAddress.contains("新疆") || receiverAddress.contains("西藏") || receiverAddress.contains("海南")) {
            return decimalFormat.format(duToLeader / price * 100) + "% ";
        }
        if (receiverAddress.contains("北京") || receiverAddress.contains("上海")) {
            return decimalFormat.format(getProfitSharingRatio(regimentPriceScheme, weight, deliveryId, orderDate) * 100) + "%";
        }
        return decimalFormat.format(getProfitSharingRatio(regimentPriceScheme, weight, deliveryId, orderDate) * 100) + "% ";
    }
}
